package net.takela.dict.service.impl;


import net.takela.common.cache.MemoryCache;
import net.takela.dict.dao.SysDictDao;
import net.takela.dict.model.SysDict;
import net.takela.dict.model.SysDictSearchArgs;
import net.takela.dict.service.SysDictService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

/**
 * Created by baboy on 07/12/2016.
 */
@Service
public class SysDictServiceImpl implements SysDictService {
    /**
     * 
     * @param sysDictDao
     */
    public SysDictServiceImpl(SysDictDao sysDictDao) {
        this.sysDictDao = sysDictDao;
    }

    /**
     * 
     */
    protected final SysDictDao sysDictDao;
    /**
     * 
     */
    private static final String CACHE_KEY = "sys_dict_cache_key";
    /**
     * 
     */
    private Integer cacheExpireTimeInSeconds = 60;
    /**
     * 
     */
    private static final HashMap<String, SysDict.SysDictItem> itemCachePool = new HashMap<String, SysDict.SysDictItem>();
    /**
     * 
     */
    private static final HashMap<String, SysDict> dictCachePool = new HashMap<String, SysDict>();

    /**
     * 
     * @param cacheExpireTimeInSeconds cacheExpireTimeInSeconds
     */
    @Override
    public void setCacheExpireTimeInSeconds(Integer cacheExpireTimeInSeconds) {
        this.cacheExpireTimeInSeconds = cacheExpireTimeInSeconds;
    }

    /**
     * 
     * @param dict dict
     *  @return result
     */
    @Override
    public Integer add(SysDict dict) {
        Integer ret = sysDictDao.add(dict);
        clearCache();
        return ret > 0 ? dict.getId() : null;
    }

    /**
     * 
     * @param dict dict
     *  @return result
     */
    @Override
    public boolean update(SysDict dict) {
        sysDictDao.update(dict);
        if (dict.getItems() != null) {
            sysDictDao.removeItems(dict.getId());
            for (SysDict.SysDictItem item : dict.getItems()) {
                item.setDictId(dict.getId());
            }
            sysDictDao.addItems(dict.getItems());
        }
        clearCache();
        return true;
    }

    /**
     * 
     * @param dictKey dictKey
     * @param items items
     *  @return result
     */
    @Override
    public boolean addItems(String dictKey, List<SysDict.SysDictItem> items) {
        SysDict dict = getByKey(dictKey);
        for (SysDict.SysDictItem item : items){
            item.setDictId(dict.getId());
        }
        boolean ret = sysDictDao.addItems(items);
        clearCache();
        return ret;
    }

    /**
     * 
     * @param dictKey dictKey
     *  @return result
     */
    @Override
    public boolean removeItems(String dictKey) {
        SysDict dict = getByKey(dictKey);
        boolean ret = sysDictDao.removeItems(dict.getId());
        clearCache();
        return ret;
    }

    /**
     * 
     * @param searchArgs searchArgs
     *  @return result
     */
    @Override
    public List<SysDict> search(SysDictSearchArgs searchArgs) {
        return sysDictDao.search( searchArgs);
    }

    /**
     * 
     * @param key key
     *  @return result
     */
    @Override
    public SysDict getByKey(String key) {
        refreshCache();
        return dictCachePool.get(key);
    }

    /**
     * 
     * @param dictKey dictKey
     * @param itemKey itemKey
     *  @return result
     */
    @Override
    public SysDict.SysDictItem getItem(String dictKey, String itemKey) {
        refreshCache();
        return itemCachePool.get(dictKey+"."+itemKey);
    }

    /**
     * 
     * @param dictKey dictKey
     * @param itemKey itemKey
     *  @return result
     */
    @Override
    public String getItemValue(String dictKey, String itemKey){
        SysDict.SysDictItem item = getItem(dictKey, itemKey);
        if (item != null){
            return item.getValue();
        }
        return null;
    }

    /**
     * 
     * @param dictKey dictKey
     * @param itemKey itemKey
     *  @return result
     */
    @Override
    public Object getItemTypedValue(String dictKey, String itemKey){
        SysDict.SysDictItem item = getItem(dictKey, itemKey);
        if (item != null){
            return item.getTypedValue();
        }
        return null;
    }

    /**
     * 
     */
    private void clearCache(){
        MemoryCache.remove(CACHE_KEY);
    }

    /**
     * 
     */
    private void refreshCache(){
        this.getAllDicts();
    }

    /**
     * 
     *  @return result
     */
    @Override
    synchronized public List<SysDict> getAllDicts(){
        List<SysDict> ret = (List<SysDict>)MemoryCache.get( CACHE_KEY );
        if (ret == null){
            //缓存
           ret = this.search(new SysDictSearchArgs());
            MemoryCache.set(CACHE_KEY, ret, cacheExpireTimeInSeconds);
           if(ret != null){
               for (SysDict d: ret){
                   String k1 = d.getKey();
                   dictCachePool.put(k1, d);
                   for (SysDict.SysDictItem item : d.getItems()){
                       String k2 = item.getKey();
                       itemCachePool.put(k1+"."+k2, item);
                   }
               }
           }
        }
        return ret;
    }
}
